/* IF2030 - Algorirma dan Struktur Data */
/* Kelas/Kelompok/Tahun  : 03/09/2011 */
/* Tanggal   : 2 Desember 2011 */
/* File      : main.c */
/* Deskripsi : Program Utama PromptBook */

#include "list/list.h"
#include "tanggal/tanggal.h"
#include "mesinkarstr/mesinkarstr.h"
#include "mesinargumen/mesinargumen.h"
#include "string/string.h"
#include <stdio.h>

boolean hasLoad;
string dbFile;

void printError (line msg)
/* Mencetak msg ke layar */
/* I.S: msg terdefinisi */
/* F.S: msg tercetak apa layar*/
{
    printf("Invalid command:");
    printf("\n\t%s", msg);
    printf("\nTry to type: help#");
    printf("\nto get help\n");
}

boolean LoadFile(ListPerson *LP, string filename)
/* Melakukan loading file dan memasukkannya ke list */
/* I.S: LP terdefinisi, filename juga terdefinisi */
/* F.S: LP berisi list berdasarkan file jika loading berhasil, jika tidak LP menjadi kosong */
{
    /* KAMUS LOKAL */
    Person X;
    boolean error, stop;
    line databaris;
    string mailp, mailf;
    FILE *pFile;
    int i;

    /* ALGORITMA */
    i = 0;
    error  = false;
    stop = false;
    pFile = fopen(filename,"r");
    DelAllPerson(LP);
    if (pFile !=  NULL) { /* pFile berhasil dibuka */
        fscanf(pFile, "%[^\n]", databaris);
        STARTARG(databaris);
        i++;
        if (!strcompare("@user", CArg)) {
            /* Pembacaan per baris file untuk user*/
            stop = (fscanf(pFile, "%*[\n]%[^\n]", databaris) == EOF);
            while (!stop) { /* read a databaris */
                i++;
                STARTARG(databaris);
                if ((strcompare("@friend", CArg) == 0) || error) {
                    break;
                } else {
                    if (!EndArg) {
                        strcopy(Email(Data(X)), CArg);
                        error |= (EmailSearch(LP, Email(Data(X))) != Nil);
                    } else {
                        error = true;
                    }

                    ADVARG();
                    if (!EndArg) {
                        strcopy(Nama(Data(X)), CArg);
                    } else {
                        error = true;
                    }

                    ADVARG();
                    if (!EndArg) {
                        Lahir(Data(X)) = StrToDate(CArg);
                        error |= !IsDateValid(X.DataUser.Lahir);
                    } else {
                        error = true;
                    }

                    ADVARG();
                    if (!EndArg) {
                        strcopy(Kota(Data(X)), CArg);
                    } else {
                        error = true;
                    }

                    ADVARG();
                    if (!EndArg) {
                        strcopy(Universitas(Data(X)), CArg);
                    } else {
                        error = true;
                    }

                    ADVARG();
                    if (!EndArg) {
                        strcopy(Sma(Data(X)), CArg);
                    } else {
                        error = true;
                    }

                    ADVARG();
                    if (!EndArg) {
                        error  = true;
                    }

                    if (!error) {
                        InsertPersonSort(LP, X);
                        stop = (fscanf(pFile, "%*[\n]%[^\n]", databaris) == EOF);
                        STARTARG(databaris);
                    } else {
                        break;
                    }
                }
            }

            /* Pembacaan per baris file untuk hubungan pertemanan */
            if (!error) {
                stop = (fscanf(pFile, "%*[\n]%[^\n]", databaris) == EOF);
                while (stop || (!error)) { /* read a databaris */
                    i++;
                    STARTARG(databaris);
                    if (strcompare("@end", CArg) == 0) {
                        break;
                    } else {
                        strcopy(mailp, CArg);
                        ADVARG();
                        if ((strcompare("->", CArg) == 0) && (EmailSearch(LP, mailp) != Nil)) {
                            ADVARG();
                            if (!EndArg) {
                                strcopy(mailf, CArg);
                                if (EmailSearch(LP, mailf)) {
                                    InsertFriend(&(Friend(EmailSearch(LP, mailp))), EmailSearch(LP, mailf));
                                } else {
                                    error  = true;
                                }
                            } else {
                                error  = true;
                            }
                        } else {
                            error = true;
                        }
                        if (!error) {
                            stop = (fscanf(pFile, "%*[\n]%[^\n]", databaris) == EOF);
                            STARTARG(databaris);
                        }
                    }
                }
            }
            fclose(pFile);
        } else {
            error = true;
        }
    } else { /* pFile tifak berhasil dibuka */
        error = true;
        perror("File I/O Error");
    }

    if (error) {
        DelAllPerson(LP);
        printf("Error while loading file");
        if (i != 0) {
            printf("\nLine %d: %s", i, databaris);
        }
        printf("\n");
    }

    return !(error);
}

boolean SaveFile(ListPerson LP, string filename)
/* Melakukan saving file dari list */
/* I.S: LP terdefinisi, filename juga terdefinisi */
/* F.S: file terbentuk dengan isi sesuai format list */
{
    FILE *pFile;
    addressPerson P;
    addressFriend F;
    boolean error = false;

    pFile = fopen (filename,"w");
    if (pFile != NULL) { /* pFile berhasil dibuka */

        /* Penulisan daftar pengguna */
        fprintf(pFile, "@user");
        P = First(LP);
        while (P != Nil) {
            fprintf(pFile, "\n%s", Email(Data(*P)));
            fprintf(pFile, " \"%s\"", Nama(Data(*P)));
            fprintf(pFile, " %d-%d-%d", Lahir(Data(*P)).DD, Lahir(Data(*P)).MM, Lahir(Data(*P)).YY);
            if (isBlank(Kota(Data(*P)))) {
                fprintf(pFile, " NIL");
            } else {
                fprintf(pFile, " \"%s\"", Kota(Data(*P)));
            }
            if (isBlank(Universitas(Data(*P)))) {
                fprintf(pFile, " NIL");
            } else {
                fprintf(pFile, " \"%s\"", Universitas(Data(*P)));
            }
            if (isBlank(Sma(Data(*P)))) {
                fprintf(pFile, " NIL");
            } else {
                fprintf(pFile, " \"%s\"", Sma(Data(*P)));
            }
            fprintf(pFile, "#");
            P = NextPerson(P);
        }

        /* Penulisan hubungan pertemanan */
        fprintf(pFile, "\n@friend");
        P = First(LP);
        while (P != Nil) {
            F = First(Friend(P));
            while (F != Nil) {
                fprintf(pFile, "\n%s -> %s", Email(Data(*P)), Email(Data(*((*F).Person))));
                F = NextFriend(F);
            }
            P = NextPerson(P);
        }

        /* Mengakhiri file */
        fprintf(pFile, "\n@end");
    } else {
        error = true;
        perror("File I/O Error");
    }
    fclose (pFile);

    if (error) {
        printf("Error while saving file");
    }
    return (!error);
}

void ModifyUser(ListPerson *LP, string email)
/* Melakukan modifikasi user */
/* I.S: LP terdefinisi, dan email terdapat dalam list LP */
/* F.S: User dengan id email datanya akan berubah sesuai inputan */
{
    /* KAMUS LOKAL */
    addressPerson AP;
    string nama;
    string ttl;
    string kota;
    string univ;
    string smu;
    string currvar;
    boolean ischNama = false;
    boolean ischTtl = false;
    boolean ischKota = false;
    boolean ischUniv = false;
    boolean ischSmu = false;

    /* ALGORITMA */
    AP = EmailSearch(LP, email);
    printf("Nama Lengkap (blank jika tetap): ");
    scanf("%*[\n]%[^\n]", nama);
    while (!isContain(nama, '#')) {
        printError("Masukan nama harus diakhiri dengan '#'");
        printf("\nNama Lengkap (blank jika tetap): ");
        scanf("%*[\n]%[^\n]", nama);
    }
    STARTARG(nama);
    strcopy(currvar, CArg);
    ADVARG();
    if (!EndArg) {
        printf("\tMasukan lebih dari 1 kata. Gunakan tanda \"...\" untuk frase.");
        printf("\n\tHanya kata pertama yang di proses\n");
    }
    if (!isBlank(currvar)) {
        strcopy(Nama(Data(Info(AP))), currvar);
        ischNama = true;
    }

    printf("Tanggal Lahir (dd-mm-yyyy dan blank jika tetap):");
    scanf("%*[\n]%[^\n]",ttl);
    while (!isContain(ttl, '#')) {
        printError("Masukan tanggal lahir harus diakhiri dengan '#'");
        printf("\nTanggal Lahir (dd-mm-yyyy dan blank jika tetap):");
        scanf("%*[\n]%[^\n]",ttl);
    }
    STARTARG(ttl);
    strcopy(currvar, CArg);
    ADVARG();
    if (!EndArg) {
        printf("\tMasukan lebih dari 1 kata. Gunakan tanda \"...\" untuk frase.");
        printf("\n\tHanya kata pertama yang di proses\n");
    }
    if (!isBlank(currvar)) {
        if (IsDateValid(StrToDate(currvar))) {
            ischTtl = true;
            Lahir(Data(Info(AP))) = StrToDate(currvar);
        } else {
            printf("\tTanggal tidak valid. Data tidak akan diubah.\n");
        }
    }

    printf("Kota Asal (blank jika tetap): ");
    scanf("%*[\n]%[^\n]",kota);
    while (!isContain(kota, '#')) {
        printError("Masukan kota harus diakhiri dengan '#'");
        printf("\nKota Asal (blank jika tetap): ");
        scanf("%*[\n]%[^\n]", kota);
    }
    STARTARG(kota);
    strcopy(currvar, CArg);
    ADVARG();
    if (!EndArg) {
        printf("\tMasukan lebih dari 1 kata. Gunakan tanda \"...\" untuk frase.");
        printf("\n\tHanya kata pertama yang di proses\n");
    }
    if (!isBlank(currvar)) {
        strcopy(Kota(Data(Info(AP))), currvar);
        ischKota = true;
    }

    printf("Universitas (blank jika tetap): ");
    scanf("%*[\n]%[^\n]",univ);
    while (!isContain(univ, '#')) {
        printError("Masukan universitas harus diakhiri dengan '#'");
        printf("\nUniversitas (blank jika tetap): ");
        scanf("%*[\n]%[^\n]", univ);
    }
    STARTARG(univ);
    strcopy(currvar, CArg);
    ADVARG();
    if (!EndArg) {
        printf("\tMasukan lebih dari 1 kata. Gunakan tanda \"...\" untuk frase.");
        printf("\n\tHanya kata pertama yang di proses\n");
    }
    if (!isBlank(currvar)) {
        strcopy(Universitas(Data(Info(AP))), currvar);
        ischUniv = true;
    }

    printf("SMU (blank jika tetap): ");
    scanf("%*[\n]%[^\n]",smu);
    while (!isContain(smu, '#')) {
        printError(" Masukan SMU harus diakhiri dengan '#'");
        printf("\nSMU (blank jika tetap): ");
        scanf("%*[\n]%[^\n]",smu );
    }
    STARTARG(smu);
    strcopy(currvar, CArg);
    ADVARG();
    if (!EndArg) {
        printf("\tMasukan lebih dari 1 kata. Gunakan tanda \"...\" untuk frase.");
        printf("\n\tHanya kata pertama yang di proses\n");
    }
    if (!isBlank(currvar)) {
        strcopy(Sma(Data(Info(AP))), currvar);
        ischSmu = true;
    }

    ResortListPerson(LP, AP);

    /* Pencetakan ke layar hasil perubahan */
    printf("\n\nPerubahan data pribadi %s sukses", email);
    printf("\nNama Lengkap (blank jika tetap): %s", Nama(Data(Info(AP))));
    if (ischNama) {
        printf("#");
    }
    printf("\nTanggal Lahir (dd-mm-yyyy dan blank jika tetap): ");
    printDate(Lahir(Data(Info(AP))));
    if (ischTtl) {
        printf("#");
    }
    printf("\nKota Asal (blank jika tetap): %s", Kota(Data(Info(AP))));
    if (ischKota) {
        printf("#");
    }
    printf("\nUniversitas (blank jika tetap): %s", Universitas(Data(Info(AP))));
    if (ischUniv) {
        printf("#");
    }
    printf("\nSMU (blank jika tetap): %s", Sma(Data(Info(AP))));
    if (ischSmu) {
        printf("#");
    }
    printf("\n");
}

void ModeUser(ListPerson *LP, line cmd, boolean *NextModeAdmin, string activeUser)
/* Menu mode user */
/* I.S. LP terdefinisi, cmd berisi perintah yang akan di-parsing, NextMode menyatakan state selanjutnya, activeUser adalah user yang sedang aktif */
/* F.S. Menjalankan perintah sesuai cmd, NextModeAdmin telah terisi state selanjutnya */
{
    /* KAMUS LOKAL */
    string currcmd;
    boolean error;
    addressPerson P, P1;
    addressFriend F;

    /* ALGORITMA */
    error = false;
    STARTARG(cmd);
    if (!EndArg) {
        strcopy(currcmd, CArg);
        if (strcompare(currcmd, "friend") == 0) { /* Perintah friend */
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);
                ADVARG();
                if (EndArg) { /* Menambahkan hubungan pertememanan */
                    P = EmailSearch(LP, activeUser);
                    P1 = EmailSearch(LP, currcmd);
                    if (P1 != Nil) { /* Pengecekan apakah yser-id telah terdaftar menjadi anggota */
                        if (strcompare(currcmd, activeUser) != 0) {
                            if (!IsFirstFriend(P, P1)) { /* Pengecekan hubungan pertemanan */
                                InsertFriend(&(Friend(P)), P1);
                                printf("Penambahan hubungan pertemanan dengan %s selesai\n", currcmd);
                            } else {
                                printf("Anda sudah berteman dengan %s\n", currcmd);
                                error = true;
                            }
                        } else {
                            printf("Anda tidak bisa berteman dengan diri sendiri\n");
                            error = true;
                        }
                    } else {
                        printf("Email %s belum menjadi anggota\n", currcmd);
                        error = true;
                    }

                } else {
                    error = true;
                }
            } else { /* Menampilkan daftar 1st friend karena tidak ada argumen kedua */
                P = EmailSearch(LP, activeUser);
                F = First(Friend(EmailSearch(LP, activeUser)));
                PrintTableHeader();
                while (F != Nil) {
                    PrintPersonMasking((*F).Person, IsFirstFriend((*F).Person, P));
                    F = NextFriend(F);
                }
                PrintTableFooter();
                printf("\n");
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("friend [<user-id>]#");
            }
        } else if (strcompare(currcmd, "unfriend") == 0) { /* Perintah unfriend */
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);
                ADVARG();
                if (EndArg) {
                    P = EmailSearch(LP, activeUser);
                    F = First(Friend(P));
                    while (F != Nil) { /* Melakukan pencarian data */
                        if (strcompare(currcmd, Email(Data(Info((*F).Person)))) == 0) {
                            break;
                        } else {
                            F = NextFriend(F);
                        }
                    }

                    if (F != Nil) { /* Email ada dan telah menjadi teman */
                        DelFriend(&(Friend(P)), &F);
                        printf("Penghapusan hubungan pertemanan dengan %s selesai\n", currcmd);
                    } else {
                        printf("Anda belum berteman dengan %s\n", currcmd);
                        error  = true;
                    }
                } else {
                    error = true;
                }
            } else {
                error = true;
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("unfriend <user-id>#");
            }
        } else if (strcompare(currcmd, "updatedata") == 0) { /* Perintah update data */
            ADVARG();
            if (EndArg) {
                ModifyUser(LP, activeUser);
            } else {
                error = true;
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("updatedata#");
            }
        } else if (strcompare(currcmd, "birthday") == 0) { /* Perintah penampilan berdasarkan ulang tahun */
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);
                ADVARG();
                if (EndArg) {
                    printf("Teman yang berulang tahun dalam rentang %d hari mendatang semenjak ", atoi(currcmd));
                    printDate(NOW());
                    PrintBirthday(LP, activeUser, NOW(), atoi(currcmd));
                } else {
                    error = true;
                }
            } else {
                printf("Teman yang berulang tahun dalam rentang 7 hari mendatang semenjak ");
                printDate(NOW());
                PrintBirthday(LP, activeUser, NOW(), 7);
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("birthday [<day>]#");
            }
        } else if (strcompare(currcmd, "same") == 0) { /* Perintah pencetakan teman sekolah/hometown yang sama */
            ADVARG();
            strcopy(currcmd, CArg);
            if ((!EndArg) && ((strcompare(currcmd, "school") == 0) || (strcompare(currcmd, "hometown") == 0))) {
                ADVARG();
                if (EndArg) {
                    PrintSamePerson(*LP,EmailSearch(LP,activeUser),currcmd);
                    printf("\n");
                } else {
                    error  = true;
                }
            } else {
                error = true;
            }
            if (error) {
                printError("same [school|hometown]#");
            }
        } else if (strcompare(currcmd, "notfriendyet") == 0) { /* Perintah pencetakan teman kedua/ketiga yang belum menjadi teman pertama */
            P = EmailSearch(LP, activeUser);
            P1 = First(*LP);

            ADVARG();
            if (EndArg) {
            /* Pencetakan teman kedua */
            printf("2nd Friend");
            while (P1 != Nil) {
                if (WhichFriend(P, P1) == 2) {
                    if (strcompare(activeUser, Email(Data(Info(P1)))) != 0) {
                        printf("\n%s\t%s", Email(Data(Info(P1))), Nama(Data(Info(P1))));
                    }
                }
                P1 = NextPerson(P1);
            }
            printf("\n");

            /* Pencetakan teman ketiga */
            P1 = First(*LP);
            printf("\n\n3rd Friend");
            while (P1 != Nil) {
                if (WhichFriend(P, P1) == 3) {
                    if (strcompare(activeUser, Email(Data(Info(P1)))) != 0) {
                        printf("\n%s\t%s", Email(Data(Info(P1))), Nama(Data(Info(P1))));
                    }
                }
                P1 = NextPerson(P1);
            }
            printf("\n");
            } else {
                error = true;
            }
            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("notfriendyet#");
            }
        }  else if (strcompare(currcmd, "help") == 0) { /* Perintah pencetakan help */
            printf("Help on User Mode");
            printf("\n=================");
            printf("\nfriend [<user-id>]#");
            printf("\n\tPerintah friend# akan mencetak first friend ke layar");
            printf("\n\tJika diikuti oleh <user-id> maka akan menambah pertemanan dengan <user-id> tersebut");
            printf("\n");
            printf("\nunfriend <user-id>#");
            printf("\n\tPerintah untuk menghapus hubungan pertemanan dengan <user-id>");
            printf("\n");
            printf("\nupdatedata#");
            printf("\n\tMengubah data pribadi user");
            printf("\n");
            printf("\nbirthday [<day>]#");
            printf("\n\tMenampilkan teman yang berulang tahun dalam <day> hari mendatang");
            printf("\n\tJika tidak diberikan <day>, akan menampilkan teman yang berulang tahun dalam 7 hari mendatang");
            printf("\n");
            printf("\nsame [school|hometown]#");
            printf("\n\tMenampilkan teman yang memiliki sekolah sama atau kota yang sama");
            printf("\n");
            printf("\nnotfriendyet#");
            printf("\n\tMenampilkan teman kedua dan ketiga yang belum menjadi teman pertama");
            printf("\n");
            printf("help#");
            printf("\tMenampilkan bantuan dalam setian modenya");
            printf("\n");
            printf("\nclose#");
            printf("\n\tMengakhiri mode user");
            printf("\n");
        } else if (strcompare(currcmd, "close") == 0) { /* Perintah keluar mode user */
            ADVARG();
            if (EndArg) {
                strcopy(activeUser, "");
                *NextModeAdmin = true;
            } else {
                printError("close#");
            }
        } else {
            printError("Not a recognized command.");
        }
    } else {
        printError("Blank command.");
    }
}

void ModeAdmin(ListPerson *LP, line cmd, boolean *NextModeAdmin, string activeUser, boolean *stop)
/* Menu mode user */
/* I.S. LP terdefinisi, cmd berisi perintah yang akan di-parsing, NextMode menyatakan state selanjutnya, activeUser adalah user yang sedang aktif */
/* F.S. Menjalankan perintah sesuai cmd, NextModeAdmin telah terisi state selanjutnya */
{
    string currcmd;
    boolean error;
    Person X;
    addressPerson P;

    error = false;
    STARTARG(cmd);
    if (!EndArg) {
        strcopy(currcmd, CArg);

        if (strcompare(currcmd, "load") == 0) {
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);
                ADVARG();
                if (EndArg) {
                    error = !(LoadFile(LP, currcmd));
                    strcopy(dbFile, currcmd);
                    if (!error) {
                        hasLoad =  true;
                        printf("File loaded: %s\n", dbFile);
                    }
                } else {
                    error = true;
                }
            } else {
                error = true;
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("load <file_name>#");
            }

        } else if ((strcompare(currcmd, "user") == 0) && (hasLoad)) {
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);
                ADVARG();
                if (EndArg) {
                    if (EmailSearch(LP, currcmd)) {
                        strcopy(activeUser, currcmd);
                        *NextModeAdmin = false;
                    } else {
                        error = true;
                        printf("Email does not found.\n");
                    }
                } else {
                    error = true;
                }
            } else {
                error = true;
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("user <user-id>#");
            }

        } else if ((strcompare(currcmd, "save") == 0) && (hasLoad)) {
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);
                ADVARG();
                if (EndArg) {
                    /* Simpan file, tarush status keberhasilan di error */
                    error = !(SaveFile(*LP, currcmd));
                    if (!error) {
                        printf("Saved: %s\n", currcmd);
                    }
                } else {
                    error = true;
                }
            } else {
                /* Simpan file di file terakhir yang di load. */
                error = !(SaveFile(*LP, dbFile));
                if (!error) {
                    printf("Saved: %s\n", dbFile);
                }
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("save [<nama-file-input>]#");
            }
        } else if ((strcompare(currcmd, "reload") == 0) && (hasLoad)) {
            ADVARG();
            if (EndArg) {
                error = !(LoadFile(LP, dbFile));
                hasLoad =  true;
                if (!error) {
                    printf("File reloaded: %s\n", dbFile);
                }
            } else {
                error = true;
            }


            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("reload#");
            }

        } else if ((strcompare(currcmd, "adduser") == 0) && (hasLoad)) {
            ADVARG();
            if (!EndArg) {
                strcopy(Email(Data(X)), CArg);
            } else {
                error = true;
            }

            ADVARG();
            if (!EndArg) {
                strcopy(Nama(Data(X)), CArg);
            } else {
                error = true;
            }

            ADVARG();
            if (!EndArg) {
                Lahir(Data(X)) = StrToDate(CArg);
                error |= !IsDateValid(X.DataUser.Lahir);
            } else {
                error = true;
            }

            ADVARG();
            if (!EndArg) {
                strcopy(Kota(Data(X)), CArg);
            } else {
                error = true;
            }

            ADVARG();
            if (!EndArg) {
                strcopy(Universitas(Data(X)), CArg);
            } else {
                error = true;
            }

            ADVARG();
            if (!EndArg) {
                strcopy(Sma(Data(X)), CArg);
            } else {
                error = true;
            }

            ADVARG();
            if (!EndArg) {
                error  = true;
            }

            if (!error) {
                if (EmailSearch(LP, Email(Data(X))) == Nil) {
                    InsertPersonSort(LP, X);
                    printf("Penambahan user dengan ID: %s sukses\n", Email(Data(X)));
                } else {
                    error = true;
                    printf("\nThis email has been registered. Try another email.\n");
                }
            } else {
                error = true;
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("adduser <email> <nama> <tgl-lahir> <kota-asal> <universitas> <SMU>#");
            }

        } else if ((strcompare(currcmd, "modifyuser") == 0) && (hasLoad)) {
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);

                /* Mencari apakah email inputan valid */
                if (EmailSearch(LP, currcmd) != Nil) {
                    ModifyUser(LP, currcmd);
                } else {
                    error = true;
                    printf("\nThis email has not been registered. Try another email.");
                }
            } else {
                error = true;
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("modifyuser <user-id>#");
            }

        } else if ((strcompare(currcmd, "deluser") == 0) && (hasLoad)) {
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);

                /* Mencari apakah email inputan valid */
                P = EmailSearch(LP, currcmd);
                if (P != Nil) {
                    if (First(*LP)!=Nil) {
                        DelPerson(LP, &P);
                    } else {
                        printf("There are no registered user.\n");
                    }
                } else {
                    error = true;
                    printf("\nThis email has not been registered. Try another email.\n");
                }
            } else {
                error = true;
            }

            /* Mengeluarkan pesan kesalahan */
            if (error) {
                printError("deluser <user-id>#");
            }

        } else if ((strcompare(currcmd, "list") == 0) && (hasLoad)) {
            ADVARG();
            if (!EndArg) {
                strcopy(currcmd, CArg);
                if (strcompare(currcmd, "email") == 0) {
                    ADVARG();
                    strcopy(currcmd, CArg);
                    if ((EndArg) || (strcompare(currcmd, "asc") == 0)) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"email",true);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else if (strcompare(currcmd, "desc") == 0) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"email",false);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else {
                        error = true;
                    }
                } else if (strcompare(currcmd, "name") == 0) {
                    ADVARG();
                    strcopy(currcmd, CArg);
                    if ((EndArg) || (strcompare(currcmd, "asc") == 0)) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"name",true);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else if (strcompare(currcmd, "desc") == 0) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"name",false);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else {
                        error = true;
                    }
                } else if (strcompare(currcmd, "birthday") == 0) {
                    ADVARG();
                    strcopy(currcmd, CArg);
                    if ((EndArg) || (strcompare(currcmd, "asc") == 0)) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"birthday",true);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else if (strcompare(currcmd, "desc") == 0) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"birthday",false);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else {
                        error = true;
                    }
                } else if (strcompare(currcmd, "hometown") == 0) {
                    ADVARG();
                    strcopy(currcmd, CArg);
                    if ((EndArg) || (strcompare(currcmd, "asc") == 0)) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"hometown",true);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else if (strcompare(currcmd, "desc") == 0) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"hometown",false);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else {
                        error = true;
                    }
                } else if (strcompare(currcmd, "university") == 0) {
                    ADVARG();
                    strcopy(currcmd, CArg);
                    if ((EndArg) || (strcompare(currcmd, "asc") == 0)) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"university",true);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else if (strcompare(currcmd, "desc") == 0) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"university",false);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else {
                        error = true;
                    }
                } else if (strcompare(currcmd, "highschool") == 0) {
                    ADVARG();
                    strcopy(currcmd, CArg);
                    if ((EndArg) || (strcompare(currcmd, "asc") == 0)) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"highschool",true);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else if (strcompare(currcmd, "desc") == 0) {
                        ADVARG();
                        if (EndArg) {
                            PrintTableHeader();
                            PrintPersonSort(LP,"highschool",false);
                            PrintTableFooter();
                        } else {
                            error = true;
                        }
                    } else {
                        error = true;
                    }
                } else {
                    error = true;
                }
            } else {
                PrintTableHeader();
                PrintPersonSort(LP,"name",true);
                PrintTableFooter();
            }

            if (error) {
                printError("list [email|name|birthday|hometown|university|highschool] [asc|desc] #");
            } else {
                printf("\n\n");
            }
        } else if (strcompare(currcmd, "help") == 0) {
            printf("Help on Admin Mode");
            printf("\n==================");
            printf("\nload <nama-file-input>#");
            printf("\n\tMe-load file jejaring sosial");
            printf("\n");

            if (hasLoad) {
                printf("\nuser <user-id>#");
                printf("\n\tMasuk ke dalam Mode User dengan user aktif <user-id>");
                printf("\n");
                printf("\nsave [<nama-file-input>]#");
                printf("\n\tMenyimpan file jejaring sosial ke <nama-file-input>");
                printf("\n\tJika tidak diberikan maka akan menyimpan ke file yang terakhir di-load");
                printf("\n");
                printf("\nreload#");
                printf("\n\tMeload file yang terakhir di-load");
                printf("\n");
                printf("\nadduser <email> <nama> <tgl-lahir> <kota-asal> <universitas> <SMU>#");
                printf("\n\tMenambahkan pengguna ke jejaring sosial");
                printf("\n");
                printf("\nmodifyuser <user-id>#");
                printf("\n\tMengubah data pengguna <user-id>");
                printf("\n");
                printf("\ndeluser <user-id>#");
                printf("\n\tMenghapus pengguna dari jejaring sosial");
                printf("\n");
                printf("\nlist [email|name|birthday|hometown|university|highschool] [asc|desc]#");
                printf("\n\tMenampilkan list pengguna yang terurut secara ascending maupun descending berdasarkan field tertentu");
                printf("\n");
            }
            printf("\nhelp#");
            printf("\n\tMenampilkan bantuan dalam setiap modenya");
            printf("\n");
            printf("about#");
            printf("\tMenampilkan tentang program ini");
            printf("\n");
            printf("\nexit#");
            printf("\n\tKeluar dari jejaring sosial");
            printf("\n");
            if (!hasLoad) {
                printf("\nNOTE:");
                printf("\n\tPerintah lainnya dapat diakses dengan melakukan load <nama-file-input># terlebih dahulu");
            }
            printf("\n\n");
        } else if (strcompare(currcmd, "about") == 0) {
            printf("PromptBook v1.0");
            printf("\n====================");
            printf("\nProgram simulasi jejaring sosial");
            printf("\nDibuat oleh:");
            printf("\n\tArief Hadi Pradana");
            printf("\n\tEdward Samuel Pasaribu");
            printf("\n\tFadhil Muhtadin");
            printf("\n\tFandi Pradhana");
            printf("\n\tMuhammad Maulidhi Hashfi");
            printf("\nSekolah Teknik Elektro dan Informatika");
            printf("\nInstitut Teknologi Bandung");
            printf("\n2011");
            printf("\n\n");
        } else if (strcompare(currcmd, "exit") == 0) {
            ADVARG();
            if (EndArg) {
                *stop = true;
            } else {
                printError("exit#");
            }
        } else {
            if (hasLoad) {
                printError("Not a recognized command.");
            } else {
                printError("Not a recognized command.\n\tPlease load database file before:\n\tload <file_name>#");
            }
        }
    } else {
        printError("Blank command.");
    }
}

int main(int argc, char *argv[]) {
	/* KAMUS */
    boolean NextAdmin;
    boolean stop = false;
    string usr;
    line cmd;
    ListPerson LP;

	/* ALGORITMA */
	/* Inisialisasi */
	NextAdmin = true;
    hasLoad = false;
    CreateListPerson(&LP);

    printf("PromptBook v.1.0");
    printf("\n==============================");

	/* Jika user ingin melakukan otomatis load */
    if (argc == 2) {
        printf("\n> load %s#\n", argv[1]);
        strcopy(dbFile, argv[1]);
        if (LoadFile(&LP, argv[1])) {
            hasLoad =  true;
            printf("File loaded: %s", dbFile);
        }
    }

	/* Masuk ke menu */
    printf("\n> ");
    scanf("%[^\n]", cmd);
    while (!isContain(cmd, '#')) {
        printError("The command must be end with '#'");
        printf("\n> ");
        scanf("%*[\n]%[^\n]", cmd);
    }

    do {
		/* Penentuan mode */
        if (NextAdmin) {
            ModeAdmin(&LP, cmd, &NextAdmin, usr, &stop);
        } else {
            ModeUser(&LP, cmd, &NextAdmin, usr);
        }

		/* Validasi perintah */
        if (!stop) {
            if (!NextAdmin) {
                printf("%s >", usr);
            }
            printf("> ");
            scanf("%*[\n]%[^\n]", cmd);

            while (!isContain(cmd, '#')) {
                printError("The command must be terminated with '#'");
                printf("\n");
                if (!NextAdmin) {
                    printf("%s >", usr);
                }
                printf("> ");
                scanf("%*[\n]%[^\n]", cmd);
            }

        }

    } while (!stop);
	
	/* Dealokasi List */
    DelAllPerson(&LP);

    return 0;
}
